103. シーンの構築: 1.インスタンシング

GPU インスタンシングを使用して、数千個のオブジェクトを同時に描画する方法を学びます。

p5.js 2.0 WebGL p5.strands Shader GLSL
Learning Tutorial

シーンの構築

パーティクルのインスタンシング

GPU は並列計算に優れているため、数千、数百万のパーティクルを同時に描画することができます。これを実現する手法が GPU インスタンシング (GPU Instancing) です。

GPU インスタンシングでは、GPU に対して同じオブジェクト(モデル)のコピーを複数描画するように指示します。各コピーにはユニークな ID(0 から n-1)が割り当てられます。この ID に基づいて、各インスタンスの位置を決定できます。例えば、各オブジェクトを座標 [ID, 0, 0] に配置すれば、X 軸に沿った一列の並びが出来上がります。

p5.js では、endShapemodel のオプション引数としてインスタンシングを利用できます。これにはカスタムシェーダーが必要です。ここでは、model を使用し、球体のジオメトリを構築してみましょう。

particleModel = buildGeometry(() => sphere(10, 2, 4));

まずは、baseColorShader() を使用して、インスタンスを X 軸方向に等間隔で並べてみます。

スケッチのソースコードを見てみましょう:

let instancingShader;
let instancingStrokeShader;
let particleModel;

function instancingCallback() {
  getWorldInputs((inputs) => {
    // インスタンス ID に基づいて各インスタンスをオフセットします
    inputs.position.x += instanceID() * 20;
    // パーティクルを画面の左側に移動します
    inputs.position.x -= 150;
    return inputs;
  });
}

async function setup() {
  createCanvas(300, 300, WEBGL);
  pixelDensity(1);
  particleModel = buildGeometry(() => sphere(10, 10, 2));
  instancingShader = baseColorShader().modify(instancingCallback);
  instancingStrokeShader = baseStrokeShader().modify(instancingCallback);
}

function draw() {
  background(0);
  orbitControl();
  shader(instancingShader);
  strokeShader(instancingStrokeShader);
  model(particleModel, 16);
}

getWorldInputs() コールバックは、現在の頂点に関するデータ(positionnormaltexCoordcolor)を含む inputs 構造体を受け取ります:

getWorldInputs((inputs) => {
  // 各インスタンスを ID に応じてオフセットします
  inputs.position.x += instanceID() * 20;
  // パーティクルを画面の左側に移動します
  inputs.position.x -= 150;
  return inputs;
});

「ワールド (world)」という単語は、これが JavaScript 側で適用された translate()scale() などの変換のに実行されることを示しています。

NOTE
ワールド空間 (World Space) vs. オブジェクト空間 (Object Space) ワールド空間での移動はシーン全体を基準にした移動であり、オブジェクトのトランスフォームはオブジェクトの中心を基準にした相対的なものです。

License

Original URL: https://beta.p5js.org/tutorials/intro-to-p5-strands/

License: MIT License

Copyright (c) 2015-present p5.js contributors & The Processing Foundation